package main

import "fmt"

const (
	WHITE = iota
	BLACK
	BLUE
	RED
	YELLOW
)

type Color byte //相当于为byte类型起别名Color

//定义盒子长宽高颜色
type Box struct {
	width, height, depth float64
	color                Color
}

type BoxList []Box //定义Box的slice类型别名为BoxList

//定义Box的成员方法Volume，用于计算Box的体积
func (b Box) Volume() float64 {
	return b.width * b.height * b.depth
}

//定义Box的成员方法Volume，用于设置Box的体积，因为要修改原始Box的字段，需要传递指针
func (b *Box) SetColor(c Color) {
	b.color = c //这里也可以用 (*b).color = c，由于指针没有字段，写作bc.color时go编译器也可以自动推断
}

//定义BoxList的成员方法BiggestColor，获取BoxList里最大体积的Box的颜色
func (bl BoxList) BiggestColor() Color {
	maxV := 0.00
	retColor := Color(WHITE)
	for _, box := range bl {
		if vol := box.Volume(); vol > maxV {
			maxV = vol
			retColor = box.color
		}
	}
	return retColor
}

//定义BoxList的成员方法PaintBlack，把所有box的颜色设置成黑色
func (bl BoxList) PaintBlack() {
	for i, _ := range bl {
		bl[i].SetColor(BLACK) //尽管setColor的第一个参数为 *Box类型， 这里也不必写成 (&bl[i]).setColor(BLACK)，go编译器会将变量自动转换为地址
	}
}

//定义Color的成员方法toString, 返回Color的字符串形式
func (c Color) toString() string {
	strings := []string{"WHITE", "BLACK", "BLUE", "RED", "YELLOW"}
	return strings[c]
}

func main() {
	boxes := BoxList{
		Box{4, 4, 4, RED},
		Box{10, 10, 1, YELLOW},
		Box{1, 1, 20, BLACK},
		Box{10, 10, 1, BLUE},
		Box{10, 30, 1, WHITE},
		Box{20, 20, 20, YELLOW},
	}

	fmt.Printf("盒子个数：%d\n", len(boxes))
	fmt.Printf("第一个盒子的体积：%f cm^3\n", boxes[0].Volume())
	fmt.Printf("最后一个盒子的颜色：%s\n", boxes[len(boxes)-1].color.toString())
	fmt.Printf("最大的盒子颜色：%s\n", boxes.BiggestColor().toString())
	fmt.Println("把所有盒子刷成黑色...")
	boxes.PaintBlack()
	fmt.Printf("第二个盒子的颜色：%s\n", boxes[1].color.toString())
	fmt.Printf("最大的盒子的颜色：%s\n", boxes.BiggestColor().toString())
}
